<?php

class Service_Route_Wildcard extends BaseObject {

	protected $routePriority = 0;
	protected $urlPriority = 0;
	/**
	 * Converts route wildcard to regexp
	 */
	protected function _wcdToRe($wcd) {
		$wcd = preg_quote($wcd, '/');
		$wcd = str_replace('%s', '([\\w]+)', $wcd);
		$wcd = str_replace('%d', '([\\d]+)', $wcd);
		$wcd = "/^$wcd$/";
		return $wcd;
	}
	
	protected function _forward($path) {
		foreach($this->route as $wcd=>$rt) {
			$re = $this->_wcdToRe($wcd);
			if(preg_match($re, $path, $parts)) {
				$res = $rt;
				array_shift($parts);
				foreach($res['#args'] as $i=>$key) {
					$res[$key]=@$parts[$i];
				}
				unset($res['#args']);
				return($res);
			}
		}		
	}
	/**
	 * Processes the array of arguments (route) to get a URL (path) 
	 */
	public function _backward($route) {
		foreach($this->route as $wcd=>$rt) {
			$rtNoArgs = $rt;
			unset($rtNoArgs['#args']);
			//var_dump($rtNoArgs);
			if($rtNoArgs == array_intersect_assoc($rtNoArgs, $route)) {
				$rest = (array_diff($route,$rt));
				if(is_array(@$rt['#args'])) {
					if(array_intersect(array_keys($rest), $rt['#args']) == $rt['#args']) {
						$vsargs = array();
						foreach($rt['#args'] as $argName) {
							$vsargs[]=$rest[$argName];
							unset($rest[$argName]);
						}
						
						$url = vsprintf($wcd,$vsargs);
					}
				} else {
					$url = $wcd;
				}
				if(is_array($rest) && count($rest)) {
					$url.='?'.http_build_query($rest);
				};
				return $url;
			}
		}
	}
	
	public function slotRoute(&$path, &$final) {
		$r = $this->_forward($path);
		if(null!==$r) {
			$final = true;
			return $r;
		}
	}
	
	public function slotUrl(&$route, &$final) {
		$u = $this->_backward($route);
		if(null!==$u) {
			$final = true;
			return $u;
		}
	}
	
	public function  __construct() {
		$this->signal()->subscribe('route', array($this, 'slotRoute'), $this->routePriority);
		$this->signal()->subscribe('url', array($this, 'slotUrl'), $this->urlPriority);
	}
}
